#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "lenet5.h"

int main(int argc, char const *argv[])
{
	
	// Declaration and Initizing inputs / kernals / outputs of each layer 
	int i , j, k, l,num ;
	int input[input_H][input_W] = { { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0} , 
									{ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0} , 
									{ 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0} ,
									{ 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0} ,
									{ 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0} ,

									{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0} , 
									{ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0} , 
									{ 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0} ,
									{ 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0} ,
									{ 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0} ,

									{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0} , 
									{ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0} , 
									{ 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0} ,
									{ 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0} ,
									{ 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0} ,

									{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0} , 
									{ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0} , 
									{ 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0} ,
									{ 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0} ,
									{ 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0} ,
									{ 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0} 
							};

	int kernel[nb_filter_conv_1][kernel_H][kernel_W] =   {
								{ 
								  { 1, 0, 1, 1, 0} , 
								  { 0, 1, 0, 0, 1} , 
						          { 1, 0, 1, 1, 1} ,
						          { 0, 0, 0, 0, 1} , 
						          { 0, 0, 1, 1, 1} 
						      	},
						      	{ 
								  { 0, 0, 0, 0, 1} , 
								  { 0, 0, 1, 0, 1} , 
						          { 1, 0, 1, 1, 1} ,
						          { 0, 1, 0, 0, 1} , 
						          { 1, 0, 1, 1, 1} 
						      	},
						      	{ 
								  { 1, 0, 0, 1, 1} , 
								  { 0, 1, 1, 0, 1} , 
						          { 1, 0, 1, 1, 1} ,
						          { 0, 1, 1, 0, 1} , 
						          { 0, 0, 1, 0, 0}  
						      	},
						      	{ 
								  { 1, 0, 1, 0, 1} , 
								  { 0, 1, 1, 0, 1} , 
						          { 1, 0, 1, 1, 1} ,
						          { 0, 1, 0, 0, 1} , 
						          { 0, 1, 1, 0, 0}  
						      	},

						      } ;

	int output[nb_filter_conv_1][outputH_1c][outputW_1c];
	int output_P[nb_filter_pool_1][outputH_1p][outputW_1p];
	
	
	memset(output,0,sizeof(output));
	memset(output_P,0,sizeof(output_P));
	
	affiche_input(input);

	// First convolutional layer   

	conv1_1(input,kernel,output);
	
	// Print results of 1st conv

	printf("Output conv1 ====> : \n{ \n");
	for (num = 0 ; num < nb_filter_conv_1 ; num++){	
		printf(" { \n");
		for (i = 0 ; i < outputH_1c ; i++ ){
	 		printf("  { ");
	 		for ( j = 0 ; j < outputW_1c ; j++){
	 			if (j != outputW_1c-1)
	 				printf("%d, ", output[num][i][j] );
	 			else 
	 				printf("%d ", output[num][i][j] );
	 		}
	 		if (i != outputW_1c-1)
	 			printf("}, \n");
	 		else 
	 			printf("} \n");
		}
		if (num != nb_filter_conv_1-1)
			printf(" }, \n");
		else 
			printf(" }\n");
	}
	
	printf("}\n");

	// first average pooling layer (subsampling)
	avg_pool_1(output[0],output_P);

	// Print results of 2nd conv 
	

	printf("Output pool1 ====> : \n{ \n");
	for(num = 0 ; num < nb_filter_pool_1 ; num++){
		printf(" { \n");
		for (i = 0 ; i < outputH_1p ; i++ ){
		 	printf("  { ");
		 	for ( j = 0 ; j < outputW_1p ; j++){
		 		if (j != outputH_1p-1)
		 			printf("%d, ", output_P[num][i][j] );
		 		else 
		 			printf("%d ", output_P[num][i][j] );
		 	}
		 	if (i != outputH_1p-1)
		 		printf("}, \n");
		 	else 
		 		printf("} \n");
		}
		if (num != nb_filter_pool_1-1)
		printf(" },\n");
		else 
		printf(" }\n");
		
	}
	printf("}\n");

	return 0;
}



/*



void conv_2()

void pool_2()

void fully_connected()
*/





